package com.beiding.natago2.component;

import com.beiding.dbrequest.common.Mapping;
import com.beiding.dbrequest.common.Request;
import com.beiding.natago2.data.ByteData;
import com.beiding.natago2.store.ChannelStore;
import com.beiding.natago2.utils.DataParser;
import com.beiding.natago2.utils.MyPrint;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.java.Log;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 公共接口
 */
@Log
public class CsCommon {

    private Boolean debugger = false;

    /**
     * 延时关闭的秒数
     */
    private long delayCloseSeconds = 10;

    private String dataParse = "string;utf8";

    /**
     * 通道存储,内部存储所有已连接的通道
     */
    ChannelStore channelStore = new ChannelStore();

    private static final ScheduledExecutorService closeTaskExecutor = Executors.newScheduledThreadPool(1);

    /**
     * 关闭通道
     *
     * @param request
     */
    @Mapping("/close")
    public void closeChannel(Request request) {
        Long id = (Long) request.getBody();

        //不能立刻关闭,应该保留一段时间,因为数据源可能有待发数据

        closeTaskExecutor.schedule(() -> {
            channelStore.close(id);
            log.info(this.getClass() + "被动关闭通道" + id);
        }, delayCloseSeconds, TimeUnit.SECONDS);

    }

    /**
     * 数据写入
     *
     * @param request
     * @return
     */
    @Mapping("/onData")
    public void onData(Request request) throws InterruptedException {
        ByteData byteData = (ByteData) request.getBody();
        ChannelHandlerContext channelHandlerContext = channelStore.get(byteData.getId());
        if (debugger) {
            byte[] data = byteData.getData();
            printData("===>>>", data, "-------");
        }
        if (channelHandlerContext == null) {
            log.info(this.getClass() + "目标通道已被关闭无法发送数据" + byteData.getId());
            throw new RuntimeException(this.getClass() + "目标通道已被关闭" + byteData.getId());
        }
        channelHandlerContext.writeAndFlush(byteData.getData()).sync();
    }

    public void setDebugger(boolean debugger) {
        this.debugger = debugger;
    }

    public Boolean getDebugger() {
        return debugger;
    }

    public long getDelayCloseSeconds() {
        return delayCloseSeconds;
    }

    public void setDelayCloseSeconds(long delayCloseSeconds) {
        this.delayCloseSeconds = delayCloseSeconds;
    }

    public String getDataParse() {
        return dataParse;
    }

    public void setDataParse(String dataParse) {
        this.dataParse = dataParse;
    }

    protected void printData(String firstLine, byte[] data, String endLine) {
        MyPrint.print(firstLine);
        MyPrint.print(DataParser.parse(data, this.dataParse));
        MyPrint.print(endLine);
    }

}


